import collections
import os
from functools import lru_cache

from settings import PG
import constants as c
from PIL import Image


def get_image(x, y, width, height, sprite_sheet):
    """Extracts image from sprite sheet"""
    image = PG.Surface([width, height])

    image.blit(sprite_sheet, (0, 0), (x, y, width, height))
    image.set_colorkey(c.ColorTuple.BLACK.value)

    return image


@lru_cache
def load_all_gfx(directory):
    result = _load(directory)
    return result


def _load(directory, color_key=(255, 0, 255), accept=('.png', 'jpg', 'bmp')):
    graphics = collections.defaultdict(tuple)
    for dir1 in os.listdir(directory):
        x, y = dir1.split("-")
        base_dir = os.path.join(directory, dir1)
        for pic in os.listdir(base_dir):
            name, ext = os.path.splitext(pic)
            if ext.lower() in accept:
                img = PG.image.load(os.path.join(base_dir, pic))
                if img.get_alpha():
                    img = img.convert_alpha()
                else:
                    img = img.convert()
                    img.set_colorkey(color_key)
                graphics[name] = (img, int(x), int(y))
    return graphics


@lru_cache
def create_sprite_dict(sheet_key):
    """
    Make a dictionary of images from sprite sheet.
    """
    gfx = load_all_gfx(c.GRAPHICS_PATH)
    val = sheet_key.split(".")
    sheet = gfx[val[0]]
    x_len = sheet[1]
    y_len = sheet[2]
    img = Image.open(os.path.join(os.path.join(c.GRAPHICS_PATH, f"{x_len}-{y_len}"), sheet_key))
    width, height = img.size
    image_list = []

    _col = width // x_len
    _row = height // y_len
    for row in range(y_len):
        for column in range(x_len):
            image_list.append(
                get_image(column * _col, row * _row, _col, _row, sheet[0]))

    return image_list


@lru_cache()
def cause_damage(damage, defense):
    d = damage / 100
    return round(d * (1 - defense / (defense + 100)), 2)
